(function()
{
    function findElementByNameAttribute( tagName, parEl, name, checktxt )
    {
        var taNodes = parEl.getElementsByTagName(tagName);
        var retval = [];
        for (var ii = 0; ii < taNodes.length; ii++)
        {
            var childEl = taNodes[ii];
            var msg = childEl.getAttribute("name");
            if ((!msg) && checktxt && (childEl.childNodes.length > 0) && (childEl.childNodes[0].nodeType == 3))
            {
//                lucidapi.debug("got here! %d", childEl.childNodes[0].nodeType);
                msg = childEl.childNodes[0].nodeValue;
            }
            if (name == msg)
            {
                if (checktxt)
                    retval.push(childEl);
                else
                    return childEl;
            }
        }
        if (checktxt)
            return retval;
        else
            return null;
    }

    function getBodyTextarea()
    {
        var focused = document.commandDispatcher.focusedElement;
        if (focused && focused.ownerDocument && (focused.ownerDocument.domain == "mail.google.com"))
        {
            return findElementByNameAttribute("textarea", focused.ownerDocument, "body");
        }
        return null;
    }

    function handleGmailEncrypt(el)
    {
        var fromstr = "";
//        var bodyTa = findElementByNameAttribute("textarea", el.ownerDocument, "body");
        if (lucidapi.config.google_mail_autopop_sigkey)
        {
            var fromsel = findElementByNameAttribute("select", el.ownerDocument, "from");
            if (fromsel)
            {
                fromstr = fromsel.value;
            }
            else
            {
                fromsel = findElementByNameAttribute("input", el.ownerDocument, "from");
                if (fromsel)
                    fromstr = fromsel.value;
            }
        }
        var preselect = [];
        if (lucidapi.config.google_mail_autopop_enckey)
        {
            var tosrchstr = findElementByNameAttribute("textarea", el.ownerDocument, "to").value;
            tosrchstr += "," + findElementByNameAttribute("textarea", el.ownerDocument, "cc").value;
            tosrchstr += "," + findElementByNameAttribute("textarea", el.ownerDocument, "bcc").value;
            var emailRe = /\w+([\.-]?\w+)*@\w+([\.-]?\w+)*\.((com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum)|\w{2})/
            var mymatch = emailRe.exec(tosrchstr);
            while (mymatch)
            {
                var lastmatch = mymatch[0];
                preselect.push(lastmatch);
                tosrchstr = tosrchstr.substr(mymatch.index + lastmatch.length);
                mymatch = emailRe.exec(tosrchstr);
            }
        }
//        var cryptoCallback = new GmailOperator(bodyTa);

        return {opname:'encrypt',preselect:preselect, presig:fromstr};
    }

    function addComposeButtons( parEl )
    {
        var retval = false;
//        var taNodes = parEl.getElementsByTagName("button");
        var taNodes = findElementByNameAttribute("button", parEl, "Discard", true);
        for (var ii = 0; ii < taNodes.length; ii++)
        {
            var childEl = taNodes[ii];
            if (childEl.nextSibling && (childEl.nextSibling.textContent != "Encrypt"))
            {
                var parNode = childEl.parentNode;
                var encryptButton = parNode.ownerDocument.createElement("button");
                encryptButton.textContent = "Encrypt";
                encryptButton.addEventListener("click", function() { goDoCommand('lucidcmd_encrypt'); }, false);
                parNode.insertBefore(encryptButton,childEl.nextSibling);
                retval = true;
            }
        }
        return retval;
    }

    function handleBubblingLoad( event )
    {
        var elem = event.target;
        var name = elem.localName;
        if (name == "DIV")
        {
            addComposeButtons(elem.ownerDocument);
        }
    }

    var GmailOperator = lucidapi.CryptoOperator.extend(function(classref) { return {
        initialize: function()
        {
            classref.superClass.initialize.call(this,window);
        },
        registerAsController: function()
        {
            this.m_win.controllers.insertControllerAt(0,this);
//            this.bodyTa.ownerDocument.defaultView.controllers.appendController(this);
        },
        getInvocationTarget: function()
        {
            var bodyTa = getBodyTextarea();
            if (bodyTa)
                return bodyTa.value;
            return null;
        },
        handleInplaceResult: function( resultobj )
        {
            var bodyTa = getBodyTextarea();
            if (bodyTa)
            {
                bodyTa.value = resultobj.m_result;
                return true;
            }
            return false;
        },
        supportsCommand : function( cmd ) {
            return (cmd == "lucidcmd_encrypt" && (getBodyTextarea()));
        },
        isCommandEnabled : function( cmd ) {
            switch (cmd) {
                case "lucidcmd_encrypt":
                    return Boolean(getBodyTextarea());
            }
            return false;
        },
        doCommand : function( cmd ) {
            try {
                var useSuper = true;
                if (cmd == "lucidcmd_encrypt") {
                    var bodyTa = getBodyTextarea();
                    if (bodyTa)
                    {
                        var invokeOpts = handleGmailEncrypt(bodyTa);
                        this.invokeOperation(invokeOpts);
                        useSuper = false;
                    }
                }
                if (useSuper)
                    return classref.superClass.doCommand.call(this, cmd);
            } finally {
                this.bodyTa = null;
            }
        }

    }});


    function getFrameSelection( selectable )
    {
        var selObj = findElementByNameAttribute("textarea", selectable.document, "body");
        if (selObj)
        {
            return selObj;
        }
        else
        {
            var frames = selectable.frames;
            if (!frames)
                return null;
            for (var ii = 0; ii < frames.length; ++ii)
            {
                selObj = getFrameSelection(frames[ii]);
                if (selObj)
                {
                    return selObj;
                }
            }
        }
        return null;
    }

    var gmailOperator = null;

    function handleGmailInjection( event )
    {
        if (event.originalTarget instanceof HTMLDocument)
        {
            var doc = event.originalTarget;
            if (doc.domain == "mail.google.com")
            {
                if (!gmailOperator)
                    gmailOperator = new GmailOperator();
                if (lucidapi.config.google_mail_encryptbutton)
                    doc.addEventListener("DOMNodeInserted", handleBubblingLoad, false);
            }
        }
    }

    if (lucidapi.config.google_mail_enabled)
    {
        window.addEventListener("load", function()
        {
            gBrowser.addEventListener("load", handleGmailInjection, true);
        }, false);
    }

})();

